﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Utils;
using System.Windows.Input;
using System.Xml.Linq;
using System.Windows.Forms;
using System.IO;

namespace MoodLaZik.ViewModel
{
    public class PlaylistVM : ViewModelBase
    {
        #region Fields
        private String _title, _type, _duration;
        private ObservableCollection<MediaData> _playlistCollection;
        private MediaData _selecteditems;
        private bool _generatevisibility;
        private readonly ICommand _generatecmd, _deletecmd, _librarypathcmd;
        private MoodLaZik.Model.XmlManipulator _xm;
        public static Dictionary<String, String> _songvspath;
        #endregion

        #region Properties
        public String Title
        {
            get { return _title; }
            set
            {
                if (_title == value) return;
                _title = value;
                OnPropertyChanged("Title");
            }
        }
        public String Type
        {
            get { return _type; }
            set
            {
                if (_type == value) return;
                _type = value;
                OnPropertyChanged("Type");
            }
        }
        public String Duration
        {
            get { return _duration; }
            set
            {
                if (_duration == value) return;
                _duration = value;
                OnPropertyChanged("Duration");
            }
        }
        public String SongTitle { get; set; }
        public ObservableCollection<MediaData> PlaylistCollection
        {
            get { return _playlistCollection; }
            set
            {
                if (value == _playlistCollection) return;
                _playlistCollection = value;
                OnPropertyChanged("PlaylistCollection");
            }
        }
        public MediaData MySelectedItems
        {
            get { return _selecteditems; }
            set
            {
                if (value == _selecteditems) return;
                _selecteditems = value;
                #region Load Characteristics
                if (_selecteditems != null)
                {
                    List<String> tmp = new List<string>();
                    this._xm.getAudioCharacteristics(Model.XmlManipulator._infos, _selecteditems.SongTitle, ref tmp);
                    if (tmp.Count() != 0)
                    {
                        Title = tmp[0];
                        Duration = tmp[1];
                        Type = tmp[2];
                    }
                }
                #endregion
                OnPropertyChanged("MySelectedItems");
            }
        }
        public bool GenerateVisibility
        {
            get { return _generatevisibility; }
            set
            {
                if (_generatevisibility == value) return;
                _generatevisibility = value;
                OnPropertyChanged("GenerateVisibility");
            }
        }
        public ICommand GenerateCmd
        {
            get { return _generatecmd; }
        }
        public ICommand DeleteCmd
        {
            get { return _deletecmd; }
        }
        public ICommand LibraryPathCmd
        {
            get { return _librarypathcmd; }
        }
        #endregion

        #region Functions

        public void MoodResultExtractor(ref List<String> _mresult)
        {
            String mood = Model.XmlManipulator._infos["MOOD"];
            XDocument moodvstypeXml = XDocument.Load(Model.XmlManipulator._moodvsTypeXML);
            var mfield = (from entry in moodvstypeXml.Elements("MoodvsTypeXMLFile").Elements(mood)
                          select entry.Value);
            _mresult = new List<string>(mfield.ToList());
        }

        public void WeatherResultExtractor(ref List<String> _wresult)
        {
            String weather = Model.XmlManipulator._infos["WEATHER"];
            XDocument weathervstypeXml = XDocument.Load(Model.XmlManipulator._weathervsTypeXML);
            var mfield = (from entry in weathervstypeXml.Elements("WeathervsTypeXMLFile").Elements(weather)
                          select entry.Value);
            _wresult = new List<string>(mfield.ToList());
        }

        public void PersonnalityResultExtractor(ref List<String> _presult)
        {
            String personnality = Model.XmlManipulator._infos["PERSONNALITY"];
            XDocument personnalityvstypeXml = XDocument.Load(Model.XmlManipulator._personnalityvsTypeXML);
            var mfield = (from entry in personnalityvstypeXml.Elements("PersonnalityvsTypeXMLFile").Elements(personnality)
                          select entry.Value);
            _presult = new List<string>(mfield.ToList());
        }

        public void PlaceResultExtractor(ref List<String> _plresult)
        {
            String place = Model.XmlManipulator._infos["PLACE"];
            XDocument placevstypeXml = XDocument.Load(Model.XmlManipulator._placevsTypeXML);
            var mfield = (from entry in placevstypeXml.Elements("PlacevsTypeXMLFile").Elements(place)
                          select entry.Value);
            _plresult = new List<string>(mfield.ToList());
        }

        public void EnvResultExtractor(ref List<String> _eresult)
        {
            String env = Model.XmlManipulator._infos["ENVIRONMENT"];
            XDocument environmentvstypeXml = XDocument.Load(Model.XmlManipulator._environmentvsTypeXML);
            var mfield = (from entry in environmentvstypeXml.Elements("EnvironmentvsTypeXMLFile").Elements(env)
                          select entry.Value);
            _eresult = new List<string>(mfield.ToList());
        }

        private void GenerateFunc()
        {
            Launch();
        }
        
        private void DeleteFunc()
        {
            if (MySelectedItems == null) return;
            
            MediaData m = new MediaData();
            m = this.MySelectedItems;
            if (PlaylistCollection.Contains(m))
            {
                PlaylistCollection.Remove(m);
                this._xm.RemoveSongtitleFromAgentBrain(Model.XmlManipulator._infos, m.SongTitle);
            }
        }

        private void LibraryPathFunc()
        {
            FolderBrowserDialog f = new FolderBrowserDialog();

            f.ShowDialog();
            if (!String.IsNullOrWhiteSpace(f.SelectedPath))
            {
                Model.XmlManipulator._dirpath = f.SelectedPath;
                this._xm.SaveDirPath();
            }
        }

        public void FillView()
        {
            PlaylistCollection.Clear();
            if (!this._xm.CheckXmlFiles())
            {
                this._xm.CreateMoodvsTypeXMLFile();
                this._xm.CreateEnvironmentvsTypeXMLFile();
                this._xm.CreatePersonnalityvsTypeXMLFile();
                this._xm.CreateWeathervsTypeXMLFile();
                this._xm.CreatePlacevsTypeXMLFile();
                this._xm.CreateAgentBrainXMLFile();
                return;
            }
            if (Model.XmlManipulator._infos.Count() != 0)
            {
                String s = String.Empty;
                this._xm.SetHoursFormat(ref s);
                Model.XmlManipulator._infos["HOUR"] = s;
                List<String> tmp = new List<string>();
                this._xm.BackUpAgentBrain(Model.XmlManipulator._infos, ref tmp);
                foreach (String str in tmp)
                    PlaylistCollection.Add(new MediaData { SongTitle = str });
            }
        }

        public void Launch()
        {
            FillView();
            if (!this._xm.IsDirPathChanged())
                return;
            String str = String.Empty;
            this._xm.SetHoursFormat(ref str);
            Model.XmlManipulator._infos["HOUR"] = str;

            XDocument xmlDoc = XDocument.Load(Model.XmlManipulator._agentBrainXML);
            List<XElement> q = (from c in xmlDoc.Descendants("Sub")
                                where c.Attribute("MOOD").Value == Model.XmlManipulator._infos["MOOD"] &&
                                c.Attribute("PLACE").Value == Model.XmlManipulator._infos["PLACE"] &&
                                c.Attribute("WEATHER").Value == Model.XmlManipulator._infos["WEATHER"] &&
                                c.Attribute("ENVIRONMENT").Value == Model.XmlManipulator._infos["ENVIRONMENT"] &&
                                c.Attribute("PERSONNALITY").Value == Model.XmlManipulator._infos["PERSONNALITY"] &&
                                c.Attribute("HOUR").Value == Model.XmlManipulator._infos["HOUR"]
                                select c).ToList();
                
                if (Model.XmlManipulator._infos.Count == 0) return;
                this.GenerateVisibility = true;
                List<String> mresult, presult, plresult, eresult, wresult;
                String typesmusicprocessed = String.Empty;
                mresult = presult = plresult = eresult = wresult = new List<string>();

                this.MoodResultExtractor(ref mresult);
                this.PersonnalityResultExtractor(ref presult);
                this.PlaceResultExtractor(ref plresult);
                this.EnvResultExtractor(ref eresult);
                this.WeatherResultExtractor(ref wresult);

                typesmusicprocessed = mresult[0] + "/" + presult[0] + "/" + plresult[0] + "/" + eresult[0] + "/" + wresult[0];
                
                if (!String.IsNullOrWhiteSpace(typesmusicprocessed))
                {
                    String str2 = String.Empty;
                    if (!this._xm.GetDirPathSaved(ref str2))
                        str2 = Model.XmlManipulator._dirpath;
                    str2 = str2.TrimEnd('\r', '\n');
                    var listofsongs = from dir in Directory.EnumerateFiles(str2, "*.mp3")
                                      select dir;
                    List<string> tmp2 = new List<string>(listofsongs.ToList());
                    this._xm.AddNewFieldsInAgentBrainXMLFile(ref Model.XmlManipulator._infos, ref tmp2, typesmusicprocessed);
                    foreach (String s in tmp2)
                    {
                        String st = Path.GetFileNameWithoutExtension(s);
                        PlaylistCollection.Add(new MediaData { SongTitle = st });
                    }
                    //FillView();
            }
        }
        #endregion

        #region Ctor
        public PlaylistVM()
        {
            this._title = this._type = this._duration = String.Empty;
            this._playlistCollection = new ObservableCollection<MediaData>();
            this._selecteditems = new MediaData();
            this._generatevisibility = false;
            this._generatecmd = new MyRelayCommand(GenerateFunc) { IsEnabled = true };
            this._deletecmd = new MyRelayCommand(DeleteFunc) { IsEnabled = true };
            this._librarypathcmd = new MyRelayCommand(LibraryPathFunc) { IsEnabled = true };
            this._xm = new Model.XmlManipulator();
            _songvspath = new Dictionary<string, string>();
        }
        #endregion
    }
}

public class MediaData
{
    public string SongTitle { get; set; }
}